package com.yang.controller;

import com.alibaba.fastjson.JSONObject;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import com.tencentcloudapi.tiw.v20190919.models.TimeValue;
import com.yang.config.NoteListConfig;
import com.yang.entity.EmailTemplate;
import com.yang.entity.NoteUser;
import com.yang.entity.UserNoteInfo;
import com.yang.service.EmailTemplateServer;
import com.yang.service.NoteUserService;
import com.yang.service.UserNoteInfoService;
import com.yang.service.impl.NoteUserServiceImpl;
import com.yang.utils.*;
import com.yang.utils.info.FileUploadBean;
import com.yang.utils.info.NoteResponseInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 用户表(NoteUser)表控制层
 * @author yangdacheng
 * @since 2022-03-02 19:11:03
 */
@RestController
@RequestMapping("noteUser")
@Slf4j
public class NoteUserController {
    /**
     * 服务对象
     */
    @Resource
    private NoteUserService noteuserService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private SendEmailUtils sendEmailUtils;
    @Resource
    private UserNoteInfoService userNoteInfoService;
    @Resource
    private UtilsFactory utilsFactory;
    @Resource
    private SendTelUtils sendTelUtils;
    @Resource
    private EmailTemplateServer emailTemplateServer;
    @Resource
    private NoteListConfig noteListConfig;
    @Resource
    private FileUploadBean fileUploadBean;
    @Resource
    private FileUploadUtils fileUploadUtils;
    /**
     * 用户登陆
     * @param username
     * @param password
     * @return
     */
    @PostMapping("userLogin")
    public NoteResponseInfo userLogin(String username, String password,Boolean rememberMe){

        log.info(username+"-----"+password+"-----"+rememberMe);
        //对密码进行加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        NoteUser noteUser = noteuserService.queryUserByID(username); //根据用户输入的账号或者邮箱查询出用户信息
        boolean matches = bCryptPasswordEncoder.matches(password,noteUser.getPassword()); //比较两个密码是否相等
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        if (matches){
            Integer Time = 30; //缓存时间时间
            //生成token
            String token = utilsFactory.buildID();
            if (rememberMe){
                Time = Time * 2 * 24 * 7;
            }
            noteUser.setUserRole(noteUser.getNoteRole().getRoleName());
            redisTemplate.opsForValue().set(token, JSONObject.toJSONString(noteUser), Time,TimeUnit.MINUTES);  //存入到redis缓存中
            log.info(noteUser.toString()+"用户信息");
//            noteResponseInfo.setNoteCode(200).setNoteMessage("登陆成功").setNoteClass(noteUser);
            noteResponseInfo.setNoteCode(200).setNoteMessage("登陆成功").setNoteClass(token);
        }else{
            noteResponseInfo.setNoteCode(250).setNoteMessage("账号密码错误").setNoteClass(null);
        }
        return noteResponseInfo;
    }

    /**
     * 用户注册
     * @param noteUser
     * @return
     */
    @PostMapping("userInsert")
    public NoteResponseInfo userInsert(NoteUser noteUser,String inputCode){
        log.info(noteUser.toString());
        String getCode = (String) redisTemplate.opsForValue().get(noteUser.getUserEmail());
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        log.info("inputCode:====>"+inputCode+"getCode:"+getCode);
        if (getCode.equals(inputCode)){
            noteUser.setUserid(utilsFactory.buildID()) //设置用户编号
                    .setUserImg("https://img0.baidu.com/it/u=1056811702,4111096278&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500")  //设置默认头像
                    .setRoleId("cb1b8774b9784997bcdcb36e00134350") //设置用户角色 -- 普通用户
                    .setUserTel("") //设置用户电话
                    .setUsername(utilsFactory.userNameBuild(999999999,100000000)); //设置账号
            noteUser.setPassword(new BCryptPasswordEncoder().encode(noteUser.getPassword())); //密码加密存入
            Boolean insertResult = noteuserService.insertUser(noteUser);
            //添加用户短信数量  --- 赠送5条短信
            UserNoteInfo userNoteInfo = new UserNoteInfo();
            userNoteInfo.setNoteId(utilsFactory.buildID())
                    .setUserid(noteUser.getUserid())
                    .setNoteResidue(5);
            userNoteInfoService.insertUserNote(userNoteInfo);

            //删除缓存中验证码
            redisTemplate.opsForValue().getAndDelete(noteUser.getUserEmail());
            if (insertResult){
                noteResponseInfo.setNoteCode(200).setNoteMessage("注册成功").setNoteClass(noteUser.getUsername());
            }else {
                noteResponseInfo.setNoteCode(251).setNoteMessage("注册失败").setNoteClass(null);
            }
        }else{
            noteResponseInfo.setNoteCode(261).setNoteMessage("验证码错误").setNoteClass(null);
        }


        return noteResponseInfo;
    }

    /**
     * 发送验证码
     * @param userEmail
     * @return
     */
    @GetMapping("sendCode/{email}&{updPassword}")
    public NoteResponseInfo sendCode(@PathVariable("email") String userEmail,
                                     @PathVariable("updPassword")Boolean updPassword){
        log.info(updPassword+"----===");
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        EmailTemplate emailTemplate = emailTemplateServer.getTemplateByID("10001");
        if (userEmail!=null){
            Integer haveEmail = noteuserService.haveEmail(userEmail);  //获取邮箱是否存在
            if (updPassword){
                utilsFactory.reserveSendCode(emailTemplate,userEmail);
                return noteResponseInfo.setNoteCode(200).setNoteMessage("发送成功").setNoteClass(null);
            }
            if (haveEmail == 0){
                //不存在
                utilsFactory.reserveSendCode(emailTemplate,userEmail);
                return noteResponseInfo.setNoteCode(200).setNoteMessage("发送成功").setNoteClass(null);
//                String buildCode = utilsFactory.buildCode(); //生成验证码
//                emailTemplate.setCodeTemplate(emailTemplate.getCodeTemplate().
//                        replace("{1}", noteListConfig.getAppTitle()).replace("{2}", buildCode));
//                redisTemplate.opsForValue().set(userEmail,buildCode,60 * 15, TimeUnit.MINUTES); //放到缓存中
//                sendEmailUtils.sendCode(userEmail, emailTemplate.getCodeTemplate(), noteListConfig.getAppTitle()+"验证码");
            } else{
                //发送邮箱进行修改密码修改...
                sendEmailUtils.sendHtml(userEmail,"您的邮箱已经注册，请前往修改界面(www.littlepig.xyz/changePassword)修改密码",
                        noteListConfig.getAppTitle()+"修改密码");
                return noteResponseInfo.setNoteCode(200).setNoteMessage("发送成功").setNoteClass(null);
            }

        }else{
            noteResponseInfo.setNoteCode(260).setNoteMessage("发送失败").setNoteClass(null);
        }
        return noteResponseInfo;
    }

    /**
     * 修改用户信息
     * @param noteUser
     * @return
     */
    @PutMapping("updUser")
    public NoteResponseInfo updateUserContext(NoteUser noteUser){
        String newName = noteUser.getName(); //需要要改的新名称
        String newEmail = noteUser.getUserEmail(); //需要设置的新邮箱
        String newPwd = noteUser.getPassword(); //需要设置的新密码
        String newTel = noteUser.getUserTel(); //需要设置的新电话
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        log.info("===="+noteUser.getUserid().length());
        if (noteUser.getUserid().length()>0)
            noteUser = noteuserService.queryUserByID(noteUser.getUserid()); //获取对象信息
        else if(noteUser.getUserEmail() != null)
            noteUser = noteuserService.queryUserByID(noteUser.getUserEmail());
        else
            return noteResponseInfo.setNoteCode(500).setNoteMessage("修改失败");
        if (newEmail !=null){
            noteUser.setUserEmail(newEmail); //修改要修改的信息
        }
        if (newName != null){
            noteUser.setName(newName);
        }
        if (newPwd != null){
            noteUser.setPassword(new BCryptPasswordEncoder().encode(newPwd));
        }
        if (newTel != null){
            noteUser.setUserTel(newTel);
        }
        log.info(noteUser.toString());
        Boolean updResult = noteuserService.updateUser(noteUser); //修改信息
        if (updResult){
            noteResponseInfo.setNoteCode(200).setNoteMessage("修改成功").setNoteClass(noteUser);
        }else {
            noteResponseInfo.setNoteCode(271).setNoteMessage("修改失败").setNoteCode(null);
        }
        return noteResponseInfo;
    }


    /**
     * 邮箱验证码交验
     * @param code
     * @param email
     * @return
     */
    @PostMapping("checkEmail")
    public NoteResponseInfo checkEmailCode(String code,String email){
        log.info("code--->"+code+"--->"+email);
        //获取缓存中的验证码
        String getCode = (String)redisTemplate.opsForValue().get(email);
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        if (getCode != null && getCode.equals(code)) {
            noteResponseInfo.setNoteCode(200).setNoteMessage("验证码正确").setNoteClass(null);
        }else{
            noteResponseInfo.setNoteCode(261).setNoteMessage("验证码错误").setNoteClass(null);
        }
        return noteResponseInfo;
    }

    /**
     * 用户头像的修改
     * @param multipartFile
     * @param userid
     * @param request
     * @return
     */
    @PostMapping("updateImg")
    public NoteResponseInfo userImgUpload(@RequestParam("file") MultipartFile multipartFile,
                                          @RequestParam("userid") String userid,HttpServletRequest request){
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        String filePath = fileUploadUtils.buildMkdir(fileUploadBean.getUserImg());//生成文件路径
        log.info("文件夹路径:"+filePath);
        log.info("文件是否存在:"+fileUploadUtils.haveFile(filePath));
        String fileURL = UploadFileToTenXunYun.uploadFile(multipartFile, fileUploadBean.getUserImg(), "日程清单");
        log.info("文件上传路径:"+fileURL);
        if (fileURL != null){
            NoteUser noteUser = noteuserService.queryUserByID(userid);
            noteUser.setUserImg(fileURL);
            Boolean updImg = noteuserService.updateUser(noteUser);
            log.info("头像图片路径,"+noteUser.getUserImg());
            if (updImg){
                return noteResponseInfo.setNoteCode(200).setNoteMessage(fileURL);
            }
        }
        return noteResponseInfo.setNoteCode(1001).setNoteMessage(fileURL).setNoteClass(null);
    }

    /**
     * 给用户发送短信验证码
     * @param noteUser
     * @return
     */
    @PostMapping("sendTel")
    public NoteResponseInfo sendTel(NoteUser noteUser){
        log.info(noteUser.toString());
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        String buildCode = utilsFactory.buildCode(); //生成验证码
        redisTemplate.opsForValue().set(noteUser.getUserTel(),buildCode,10*60,TimeUnit.SECONDS); //添加到缓存中
        String templateId = "1323327";  //发送验证码模板编号
        String telNumber = noteUser.getUserTel();
        String[] templateParamSet = {buildCode};
        SendStatus sendStatus = sendTelUtils.SendCode(templateId, telNumber, templateParamSet);
        if (sendStatus.getCode().equals("Ok")){
            noteResponseInfo.setNoteCode(200).setNoteMessage("发送成功");
        }
        return noteResponseInfo;
    }

    /**
     * 用户绑定手机号
     * @param noteUser
     * @param inputCode
     * @return
     */
    @PostMapping("insertUserTel")
    public NoteResponseInfo insertUserTel(NoteUser noteUser,@RequestParam("inputCode") String inputCode){
        log.info("[insertUserTel]:noteUser:==>"+noteUser+"inputCode:"+inputCode);
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        String newTel = noteUser.getUserTel(); //缓存手机号
        String getCode = (String)redisTemplate.opsForValue().get(noteUser.getUserTel());
        if (getCode != null){
            if (getCode.equals(inputCode)){
                noteUser = noteuserService.queryUserByID(noteUser.getUserid());  //获取用户对象
                noteUser.setUserTel(newTel);
                Boolean insertTel = noteuserService.updateUser(noteUser);
                if (insertTel) {
                    noteResponseInfo.setNoteCode(200).setNoteMessage("绑定成功");
                    redisTemplate.opsForValue().getAndDelete(noteUser.getUserTel());
                }else{
                    noteResponseInfo.setNoteCode(200).setNoteMessage("绑定失败！");
                }
            }else {
                noteResponseInfo.setNoteCode(261).setNoteMessage("验证码输入错误");
            }
        }else{
            noteResponseInfo.setNoteCode(666).setNoteMessage("验证码过期请从新获取");
        }
        return noteResponseInfo;
    }

    /**
     * 校验邮箱是否存在
     * @param userEmail
     * @return
     */
    @GetMapping("findPassword/{email}")
    public NoteResponseInfo findPassword(@PathVariable("email") String userEmail){
        NoteResponseInfo noteResponseInfo = new NoteResponseInfo();
        Integer haveEmail = noteuserService.haveEmail(userEmail);
        if (haveEmail>0){
            EmailTemplate emailTemplate = emailTemplateServer.getTemplateByID("10001");
            utilsFactory.reserveSendCode(emailTemplate,userEmail);
//            String buildCode = utilsFactory.buildCode(); //生成验证码
//            emailTemplate.setCodeTemplate(emailTemplate.getCodeTemplate().
//                    replace("{1}", noteListConfig.getAppTitle()).replace("{2}", buildCode));
//            redisTemplate.opsForValue().set(userEmail,buildCode,60 * 15, TimeUnit.MINUTES); //放到缓存中
//            sendEmailUtils.sendCode(userEmail, emailTemplate.getCodeTemplate(), noteListConfig.getAppTitle()+"验证码");
        }else{
            return noteResponseInfo.setNoteCode(4041).setNoteMessage("该邮箱还没有注册,是否前往注册界面？");
        }
        return noteResponseInfo.setNoteCode(200).setNoteMessage("发送邮件成功，请注意查收！");
    }

    @GetMapping("/queryUserByToken/{token}")
    public NoteUser findUserByToken(@PathVariable("token") String token){
        return JSONObject.parseObject(String.valueOf(redisTemplate.opsForValue().get(token)),NoteUser.class);
    }
}